package com.fishingwithme.domain.anybiting;

import com.fishingwithme.infrastructure.dtos.anybiting.CircleMessageDTO;
import com.fishingwithme.infrastructure.mapper.circle.AnyBittingMapper;
import com.fishingwithme.infrastructure.mapper.circle.CircleMapper;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.UUID;

@Log4j
@Service
public class CircleMessageService {

    @Autowired
    private CircleMessageRepository messageRepository;


    @Autowired
    private AnyBittingMapper anyBittingMapper;

    @Autowired
    private CircleMapper circleMapper;

    /**
     * 发送消息
     */
    @Transactional
    public void saveMessage(CircleMessageDTO messageDTO) {
        CircleMessage message = convertToEntity(messageDTO);
        messageRepository.addMessage(messageDTO.getCityCode(), message);
        message.toJsonString();
        anyBittingMapper.insert(message);
    }

    /**
     * 获取准实时消息
     */
    public List<CircleMessage> getQuasiRealTimeMessages(String city, int limit) {
        return messageRepository.getQuasiRealTimeMessages(city, limit);
    }

    /**
     * 获取非实时消息
     */
    public List<CircleMessage> getNonRealTimeMessages(String city, String cursor, int limit, Boolean isForward) {
        return messageRepository.getNonRealTimeMessages(city, cursor, limit,isForward);
    }

    /**
     * 获取最新的游标
     */
    public String getLatestCursor(String city) {
        return messageRepository.getLatestCursor(city);
    }

    /**
     * 更新用户游标
     */
    public void updateUserCursor(String city, String userId, String cursor) {
        messageRepository.updateUserCursor(city, userId, cursor);
    }

    /**
     * 获取用户游标
     */
    public String getUserCursor(String city, String userId) {
        return messageRepository.getUserCursor(city, userId);
    }

    private CircleMessage convertToEntity(CircleMessageDTO dto) {
        try {
            CircleMessage message = new CircleMessage();
            message.setId(UUID.randomUUID().toString());
            message.setCityCode(dto.getCityCode());
            message.setType(dto.getType());
            message.setSubType(dto.getSubtype());
            message.setContent(dto.getContent());
            message.setTimestamp(dto.getTimestamp() != null ? dto.getTimestamp() : new Date());
            message.setSender(dto.getSender());
            message.setPriority(dto.getPriority() != null ? dto.getPriority() : 0);
            return message;
        } catch (Exception e) {
            log.error("convert to entity error", e);
            throw new RuntimeException(e);
        }
    }

    public List<CircleMessage> getLatestByCircleIdAndCache(String cityCode, int limit) {
        log.info("load messages from database for circleId: " + cityCode);
        List<CircleMessage> messages = anyBittingMapper.getLatestByCityCode(cityCode, limit);
        return messages.stream().peek(message -> {
            message.toJsonObj();
            messageRepository.addMessage(cityCode, message);
        }).toList();
    }
}
